package com.bbs.util;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexableField;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;

import com.bbs.dao.TopicDao;
import com.bbs.dao.impl.TopicDaoImpl;
import com.bbs.model.Topic;

/**
 * 全文检索
 * 
 * @author Administrator
 * 
 */
public class FTSutil {
	Analyzer analyzer;
	Directory directory;
	IndexSearcher isearcher;
	DirectoryReader ireader;

	public FTSutil(List<Topic> topicList) {
		super();
		createIndex(topicList);
	}

	public void createIndex(List<Topic> topicList) {
		// 分词器
		//analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);

		//实例化IKAnalyzer中文分词器 
		analyzer = new IKAnalyzer();
		
		// 在内存中建立索引
		directory = new RAMDirectory();
		// 想要在磁盘上建立索引，用下面这句代替
		// Directory directory = FSDirectory.open("/文件目录");
		// Directory directory = FSDirectory.open("/tmp/testindex");
		IndexWriter iwriter;
		IndexWriterConfig config = new IndexWriterConfig(
				Version.LUCENE_CURRENT, analyzer);
		try {
			//一个iwriter对应数据库一张表
			iwriter = new IndexWriter(directory, config);
			for (Topic topic : topicList) {
				//每一个doc对应数据库一行记录
				Document doc = new Document();
				//每一个Field对应数据库表中一个字段
				doc.add((IndexableField) new Field("title", topic.getTitle(),
						TextField.TYPE_STORED));
				doc.add((IndexableField) new Field("content", topic
						.getContent(), TextField.TYPE_STORED));
				doc.add((IndexableField) new Field("id", topic.getId() + "",
				TextField.TYPE_STORED));
				iwriter.addDocument(doc);

			}
			iwriter.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public List<Topic> searchIndex(Topic topic) {
		ScoreDoc[] hits = null;
		List<Topic> topics=new ArrayList<Topic>();
		
		BooleanQuery query = new BooleanQuery();
		try {
			//要查找帖子内容
			if (null != topic.getContent()) {
				//多个关键字用空格分隔的情况
				String[] contents = topic.getContent().trim().split(" ");
				for (String content : contents) {
					TermQuery tq = new TermQuery(new Term("content",
							content.trim()));
					 //多个Occur.MUST的组合:检索的交集
					query.add(tq, Occur.MUST);
				}
			}
			String title = topic.getTitle();
			//要查找帖子标题
			//在web中测试，struts给title ""   在程序中测试title 为null
			if (!(title.equals("")||null==title)) {
				TermQuery tq = new TermQuery(new Term("title", title));
				query.add(tq, Occur.MUST);
			}

			ireader = DirectoryReader.open(directory);
			isearcher = new IndexSearcher(ireader);
			//执行搜索 得到结果
			hits = isearcher.search(query, null, 1000).scoreDocs;
			
			Document hitDoc;
			//搜索结果封装为对象 用来在页面输出
			for (int i = 0; i < hits.length; i++) {
				Topic t=new Topic();
				hitDoc = isearcher.doc(hits[i].doc);
				topic.setContent(hitDoc.get("content"));
				topic.setTitle(hitDoc.get("title"));
				//TextField.TYPE_STORED 不存储的取不出来 
				topic.setId(Integer.parseInt(hitDoc.get("id")));
				topics.add(topic);

			}
			ireader.close();
			directory.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return topics;
	}
	/*private List<Topic> getResultTopic(ScoreDoc[] hits) {
		List<Topic> topics=new ArrayList<Topic>();
		for (int i = 0; i < hits.length; i++) {
			Document hitDoc = isearcher.doc(hits[i].doc);
			System.out.println(hitDoc.get("content"));

		}
		
	}*/

	/*public void closeReader(){
		try {
			ireader.close();
			directory.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}*/

	/*public void searchIndex(Directory directory, Analyzer analyzer) {
		ScoreDoc[] hits;
		IndexSearcher isearcher;
		// Now search the index:
		DirectoryReader ireader;
		try {
			ireader = DirectoryReader.open(directory);
			isearcher = new IndexSearcher(ireader);
			// Parse a simple query that searches for "text":
			QueryParser parser = new QueryParser(Version.LUCENE_CURRENT,
					"content", analyzer);
			Query query;
			query = parser.parse("爱情");
			hits = isearcher.search(query, null, 1000).scoreDocs;
			// Iterate through the results:
			for (int i = 0; i < hits.length; i++) {
				Document hitDoc = isearcher.doc(hits[i].doc);
				System.out.println(hitDoc.get("content"));

			}
			ireader.close();
			directory.close();
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
*/
	public static void main(String[] args) throws IOException {

		TopicDao topicDao = new TopicDaoImpl();
		List<Topic> topics = topicDao.getTopicList();
		FTSutil fts = new FTSutil(topics);
		Topic topic = new Topic();
		//topic.setTitle("我");
		//topic.setContent("challenges");
		topic.setContent("学习");
		//topic.setTitle("common");
		//topic.setContent("challenges");
		fts.searchIndex(topic);

	}

}
